package com.dd.cloud.user.service.doctor.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.cloud.common.constants.ConsultConstants;
import com.dd.cloud.common.constants.IntegralConstants;
import com.dd.cloud.common.constants.RedisKeyConstants;
import com.dd.cloud.common.constants.UserConstants;
import com.dd.cloud.common.enums.ZkExceptionEnum;
import com.dd.cloud.common.exception.ZekeException;
import com.dd.cloud.common.interceptor.UserInterceptor;
import com.dd.cloud.common.utils.*;
import com.dd.cloud.common.vo.LoginInfo;
import com.dd.cloud.common.vo.PageReq;
import com.dd.cloud.user.entity.consult.ConsultSubscribe;
import com.dd.cloud.user.entity.doctor.PatientMedCard;
import com.dd.cloud.user.entity.patient.PatientMedRank;
import com.dd.cloud.user.entity.patient.PatientUser;
import com.dd.cloud.user.entity.plat.PlatformLogin;
import com.dd.cloud.user.entity.plat.PlatformWechatInfo;
import com.dd.cloud.user.entity.pres.PresPrescription;
import com.dd.cloud.user.mapper.doctor.PatientMedCardMapper;
import com.dd.cloud.user.mq.MQConfig;
import com.dd.cloud.user.mq.RabbitSend;
import com.dd.cloud.user.req.aicms.AskDoctorParamsReq;
import com.dd.cloud.user.req.doctor.*;
import com.dd.cloud.user.req.pres.PresPatientAddrReq;
import com.dd.cloud.user.req.pres.PresPatientReq;
import com.dd.cloud.user.res.doctor.*;
import com.dd.cloud.user.service.consule.IConsultSubscribeService;
import com.dd.cloud.user.service.doctor.IDoctorPatientBindService;
import com.dd.cloud.user.service.doctor.IPatientDeliveryAddrService;
import com.dd.cloud.user.service.doctor.IPatientMedCardService;
import com.dd.cloud.user.service.patient.IPatientMedRankService;
import com.dd.cloud.user.service.patient.IPatientUserService;
import com.dd.cloud.user.service.plat.IPlatformLoginService;
import com.dd.cloud.user.service.plat.IPlatformWechatInfoService;
import com.dd.cloud.user.service.pres.IPresPrescriptionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 患者详细信息表 服务实现类
 * </p>
 *
 * @author czg
 * @since 2022-04-27
 */
@Service
@Slf4j
public class PatientMedCardServiceImpl extends ServiceImpl<PatientMedCardMapper, PatientMedCard> implements IPatientMedCardService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private IDoctorPatientBindService doctorPatientBindService;
    @Autowired
    private IPatientDeliveryAddrService patientDeliveryAddrService;
    @Autowired
    private IPatientUserService patientUserService;
    @Autowired
    private IPatientMedRankService patientMedRankService;
    @Autowired
    private RabbitSend rabbitSend;
    @Autowired
    private IPlatformWechatInfoService platformWechatInfoService;
    @Autowired
    private IPlatformLoginService platformLoginService;

    /**
     * 医生添加患者病历卡
     *
     * @param req
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PatientMedCard addPatientMedCard(PatientMedCardCreateReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        if (req.getBirthDate() == null) {
            if (req.getAgeNum() == null && req.getAgeType() == null) {
                throw new ZekeException(400, "出生日期或年龄数必须选择一个");
            }
            req.setBirthDate(DateUtils.byAgeNumAndAgeTypeToDate(req.getAgeNum(), req.getAgeType()));
        }
        if (LocalDate.now().getYear() - req.getBirthDate().getYear() < 65) {
            if (StringUtils.isBlank(req.getMobileNumber())) {
                throw new ZekeException(400, "手机号不能为空");
            }
        }
        Boolean flag1 = false;
        PatientMedCard pmc = null;
        if (!StringUtils.isBlank(req.getMedId())) {
            QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
            qw.lambda().eq(PatientMedCard::getMedId, req.getMedId());
            qw.lambda().ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
            pmc = getOne(qw);
        } else {
            if (StringUtils.isNotBlank(req.getMobileNumber())) {
                QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
                qw.lambda().eq(PatientMedCard::getMobileNumber, req.getMobileNumber());
                qw.lambda().ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
                pmc = getOne(qw);
            }
        }
        if (pmc == null) {
            pmc = new PatientMedCard();
            String medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            while (true) {
                QueryWrapper<PatientMedCard> qws = new QueryWrapper<>();
                qws.lambda().eq(PatientMedCard::getMedId, medNo);
                List<PatientMedCard> card = list(qws);
                if (card == null || card.isEmpty()) {
                    break;
                }
                medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            }
            BeanUtils.copyProperties(req, pmc);
            pmc.setMedId(medNo);
            pmc.setDoctorId(loginInfo.getId());
            pmc.setCreateId(loginInfo.getId());
            pmc.setCreateDate(LocalDateTime.now());
            pmc.setStatus(UserConstants.MedCardStatus.NORMAL);
            pmc.setNamePinyin(PinYinUtils.chineseToPinyinSell(req.getName()));
            if (pmc.getBirthDate() == null) {
                pmc.setBirthDate(LocalDate.of(1998, 10, 1));
            }
            flag1 = true;
        } else {
            req.setMedId(pmc.getMedId());
            BeanUtils.copyProperties(req, pmc);
            pmc.setNamePinyin(PinYinUtils.chineseToPinyinSell(req.getName()));
        }
        String img = getPhotoImg(req.getSex());
        pmc.setAvatar(img);
        req.setMedId(pmc.getMedId());
        boolean flag = saveOrUpdate(pmc);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
        doctorPatientBindService.doctorPatientBind(loginInfo.getId(), pmc.getMedId(), 1);
        if (flag1) {
            String params = IntegralConstants.IntegralType.SIX_TYPE + "-" + loginInfo.getId();
            log.info("邀请患者积分奖励,参数:{}", params);
            rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
        }
        return pmc;
    }


    public String getPhotoImg(String sex) {
        if ("女".equals(sex)) {
            return "https://zk-ak.obs.cn-south-1.myhuaweicloud.com/dadao/img_woman.png";
        } else if ("男".equals(sex)) {
            return "https://zk-ak.obs.cn-south-1.myhuaweicloud.com/dadao/img_man.png";
        }
        return "https://zk-ak.obs.cn-south-1.myhuaweicloud.com/dadao/img_man.png";
    }

    /**
     * 添加患者病历卡信息
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addPatientMedCardH5(PatientMedCardH5CreateReq req) {
        boolean flag1 = false;
        if (req.getBirthDate() == null) {
            if (req.getAgeNum() == null && req.getAgeType() == null) {
                throw new ZekeException(400, "出生日期或年龄数必须选择一个");
            }
            req.setBirthDate(DateUtils.byAgeNumAndAgeTypeToDate(req.getAgeNum(), req.getAgeType()));
        }
        if (LocalDate.now().getYear() - req.getBirthDate().getYear() < 65) {
            if (StringUtils.isBlank(req.getMobileNumber())) {
                throw new ZekeException(400, "手机号不能为空");
            }
        }
        PatientMedCard pmc = null;
        QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
        if (!StringUtils.isBlank(req.getMedId())) {
            qw.lambda().eq(PatientMedCard::getMedId, req.getMedId());
            qw.lambda().ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
            pmc = getOne(qw);
        } else {
            if (StringUtils.isNotBlank(req.getMobileNumber())) {
                qw.lambda().eq(PatientMedCard::getMobileNumber, req.getMobileNumber());
                qw.lambda().ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
                pmc = getOne(qw);
            }
        }
        if (pmc == null) {
            pmc = new PatientMedCard();
            BeanUtils.copyProperties(req, pmc);
            pmc.setCreateId(req.getDoctorId());
            pmc.setCreateDate(LocalDateTime.now());
            pmc.setStatus(UserConstants.MedCardStatus.NORMAL);
            pmc.setNamePinyin(PinYinUtils.chineseToPinyinSell(req.getName()));
            String medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            while (true) {
                qw.clear();
                qw.lambda().eq(PatientMedCard::getMedId, medNo);
                List<PatientMedCard> card = list(qw);
                if (card == null || card.isEmpty()) {
                    break;
                }
                medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            }
            pmc.setMedId(medNo);
            req.setMedId(medNo);
            flag1 = true;
        } else {
            String medId = pmc.getMedId();
            BeanUtils.copyProperties(req, pmc);
            req.setMedId(medId);
            pmc.setNamePinyin(PinYinUtils.chineseToPinyinSell(req.getName()));
        }
        String img = getPhotoImg(req.getSex());
        pmc.setAvatar(img);
        boolean flag = saveOrUpdate(pmc);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.ADD_ERROR);
        }
        doctorPatientBindService.doctorPatientBind(req.getDoctorId(), pmc.getMedId(), 2);
        req.setAddrH5Reqs(JSON.parseArray(req.getAddrH5ReqsJson(), PatientDeliveryAddrH5CreateReq.class));
        PatientMedCard finalPmc = pmc;
        req.getAddrH5Reqs().forEach(t -> {
            t.setMedId(finalPmc.getMedId());
        });
        patientDeliveryAddrService.addPatientDeliveryAddrsH5(req.getAddrH5Reqs());
        if (flag1) {
            String params = IntegralConstants.IntegralType.SEVEN_TYPE + "-" + req.getDoctorId();
            log.info("邀请患者积分奖励,参数:{}", params);
            rabbitSend.sendMessage(MQConfig.INTEGRAL_EXCHANGE, MQConfig.INTEGRAL_QUEUE, params);
        }
        if (StringUtils.isNotBlank(req.getOpenid())) {
            QueryWrapper<PatientMedRank> qw2 = new QueryWrapper<>();
            qw2.lambda().eq(PatientMedRank::getMedId, pmc.getMedId()).eq(PatientMedRank::getNexus, 1).eq(PatientMedRank::getStatus, 1);
            PatientMedRank medRank = patientMedRankService.getOne(qw2);
            if (medRank == null) {
                PatientUser patientUser = new PatientUser();
                patientUser.setMobileNumber(req.getMobileNumber());
                patientUser.setNickName(req.getName());
                patientUser.setStatus(1);
                patientUser.setCreateDate(LocalDateTime.now());
                patientUserService.save(patientUser);
                PatientMedRank patientMedRank = new PatientMedRank();
                patientMedRank.setPatientId(patientUser.getId());
                patientMedRank.setNexus(1);
                patientMedRank.setStatus(1);
                patientMedRank.setMedId(pmc.getMedId());
                patientMedRank.setCreateDate(LocalDateTime.now());
                patientMedRankService.save(patientMedRank);
                medRank = patientMedRank;
            }
            QueryWrapper<PlatformWechatInfo> qw3 = new QueryWrapper<>();
            qw3.lambda().eq(PlatformWechatInfo::getOpenid, req.getOpenid());
            PlatformWechatInfo one = platformWechatInfoService.getOne(qw3);
            if (one != null && !StringUtils.isBlank(one.getUnionid())) {
                QueryWrapper<PlatformLogin> qw4 = new QueryWrapper<>();
                qw4.lambda().eq(PlatformLogin::getPlatId, one.getUnionid()).eq(PlatformLogin::getUserType, LoginInfo.UserType.PATIENT);
                PlatformLogin temp = platformLoginService.getOne(qw4);
                PlatformLogin platformLogin = new PlatformLogin();
                if (temp != null) {
                    platformLogin.setId(temp.getId());
                }
                platformLogin.setPlatId(one.getUnionid());
                platformLogin.setType(1);
                platformLogin.setTitle("小程序登录");
                platformLogin.setUserId(medRank.getPatientId());
                platformLogin.setUserType(LoginInfo.UserType.PATIENT);
                platformLogin.setStatus(1);
                platformLogin.setCreateDate(LocalDateTime.now());
                platformLoginService.saveOrUpdate(platformLogin);
            }
        }
    }

    /**
     * 修改就诊卡
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMedCard(PatientMedCardUpdateReq req) {
        if (req.getBirthDate() == null) {
            if (req.getAgeNum() == null && req.getAgeType() == null) {
                throw new ZekeException(400, "出生日期或年龄数必须选择一个");
            }
            req.setBirthDate(DateUtils.byAgeNumAndAgeTypeToDate(req.getAgeNum(), req.getAgeType()));
        }
        //修改值
        PatientMedCard pmc = getById(req.getId());
        if (pmc == null || pmc.getStatus() == UserConstants.MedCardStatus.DEL) {
            throw new ZekeException(ZkExceptionEnum.UPDATE_ERROR);
        }
        BeanUtils.copyProperties(req, pmc);
        pmc.setCreateDate(LocalDateTime.now());
        pmc.setNamePinyin(PinYinUtils.chineseToPinyinSell(pmc.getName()));
        String img = getPhotoImg(req.getSex());
        pmc.setAvatar(img);
        boolean flag = updateById(pmc);
        if (!flag) {
            throw new ZekeException(ZkExceptionEnum.OPER_ERROR);
        }
    }

    /**
     * 修改就诊卡状态
     *
     * @param id     就诊卡id
     * @param status 状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMedCardStatus(Integer id, Integer status) {
        PatientMedCard medCard = getById(id);
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo().get();
        if (medCard == null) {
            throw new ZekeException(400, "就诊卡不存在");
        }
        if (medCard.getStatus().equals(status)) {
            return;
        }
        if (!ObjectUtils.refrect(UserConstants.MedCardStatus.class, status)) {
            throw new ZekeException(ZkExceptionEnum.STATUS_DATA_ERROR);
        }
        if (loginInfo.getType() == LoginInfo.UserType.DOCTOR) {
            if (status == UserConstants.MedCardStatus.DEL) {
                doctorPatientBindService.updateDoctorPatientBind(loginInfo.getId(), medCard.getMedId(), UserConstants.DoctorPatientBindStatus.DEL);
            }
            return;
        }
        medCard.setStatus(status);
        boolean i = updateById(medCard);
        if (!i) {
            throw new ZekeException(ZkExceptionEnum.DEL_ERROR);
        }
    }

    @Autowired
    private IConsultSubscribeService consultSubscribeService;

    /**
     * 查询患者信息
     *
     * @param medId
     * @return
     */
    @Override
    public PatientMedCardDetailRes queryPatientMedCardDetail(String medId) {
        PatientMedCardDetailRes res = getBaseMapper().queryPatientMedCardDetail(medId);
        if (res != null) {
            LocalDateTime localDateTime = getBaseMapper().getLastPayDate(medId);
            res.setStartDate(localDateTime);
            if (res.getUsed() > 0) {
                res.setUsed(1);
            }
            res.setNum(getNum(medId));
            //踢出来查询地址
            List<PatientMedCardAddrListH5Res> addrList = getBaseMapper().queryAddress(medId);
            res.setAddrList(addrList);
        }
        return res == null ? new PatientMedCardDetailRes() : res;
    }

    /**
     * 检查患者信息是否存在 存在返回信息
     *
     * @param req
     * @return
     */
    @Override
    public PatientMedCardDetailH5Res queryPatientMedCardDetailH5(PatientMedCardDetailH5Req req) {
        if (req.getDoctorId() != null) {
            Long num = redisTemplate.opsForValue().increment(RedisKeyConstants.DOCTOR_CHECK_PATIENT_KEY + req.getDoctorId());
            if (num != null && num == 1) {
                LocalDateTime start = LocalDateTime.now();
                LocalDateTime end = DateUtils.getStartTimeOfDay(LocalDate.now().plusDays(1));
                long sec = Duration.between(start, end).getSeconds();
                redisTemplate.expire(RedisKeyConstants.DOCTOR_CHECK_PATIENT_KEY + req.getDoctorId(), sec, TimeUnit.SECONDS);
            }
            if (num != null && num > 50) {
                throw new ZekeException(400, "当日医生检索患者信息超过50次禁止检索");
            }

        }
        if (StringUtils.isBlank(req.getPhone())) {
            if (StringUtils.isBlank(req.getName()) || StringUtils.isBlank(req.getIdCard())) {
                throw new ZekeException(400, "手机号或者姓名身份证两组参数必传一组");
            }
        } else {
            req.setName(null);
            req.setIdCard(null);
        }
        PatientMedCardDetailH5Res res = getBaseMapper().queryPatientMedCardDetailH5(req);
        if (res != null) {
            res.setUsed(res.getUsed() > 0 ? 1 : 0);
        }
        return res == null ? new PatientMedCardDetailH5Res() : res;
    }

    /**
     * 查询病历卡分页
     *
     * @param req
     * @return
     */
    @Override
    public IPage<PatientMedCardPageRes> selPatientMedCard(ParamsMedCardReq req) {
        LoginInfo li = UserInterceptor.getLoginUserInfo().get();
        if (li.getType() == LoginInfo.UserType.DOCTOR) {
            req.setDocId(li.getId());
        }
        Page<PatientMedCardPageRes> iPage = req.pagePojo();
        iPage = getBaseMapper().getPatientMedCardPage(iPage, req);
        return iPage;
    }

    /**
     * 分页查询患者病历卡信息
     *
     * @param req
     * @return
     */
    @Override
    public IPage<PatientMedCardMobPageRes> selPatientMedCardMobPage(ParamsMedCardMobPageReq req) {
        if (req.getVerifyNum() == 1) {
            LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
            Long num = redisTemplate.opsForValue().increment(RedisKeyConstants.DOCTOR_CHECK_PATIENT_KEY + loginInfo.getId());
            if (num != null && num == 1) {
                LocalDateTime start = LocalDateTime.now();
                LocalDateTime end = DateUtils.getStartTimeOfDay(LocalDate.now().plusDays(1));
                long sec = Duration.between(start, end).getSeconds();
                redisTemplate.expire(RedisKeyConstants.DOCTOR_CHECK_PATIENT_KEY + loginInfo.getId(), sec, TimeUnit.SECONDS);
            }
            if (num != null && num > 50) {
                throw new ZekeException(400, "当日医生检索患者信息超过50次禁止检索");
            }

        }
        IPage<PatientMedCardMobPageRes> iPage = req.pagePojo();
        iPage = getBaseMapper().selPatientMedCardMobPage(iPage, req);
        for (PatientMedCardMobPageRes item : iPage.getRecords()) {
            item.setUsed(item.getUsed() > 0 ? 1 : 0);
        }
        return iPage;
    }

    /**
     * 查询病历卡简要信息列表
     *
     * @param req
     * @return
     */
    @Override
    public List<PatientMedCardListRes> selPatientMedCardList(ParamsMedCardListReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        req.setMechanId(loginInfo.getMechanId());
        return getBaseMapper().getPatientMedCardList(req);
    }

    /**
     * 查询就诊卡诊断的机构
     *
     * @param medId
     * @return
     */
    @Override
    public List<MedMechanListRes> getMedMechanList(String medId) {
        return getBaseMapper().getMedMechan(medId);
    }

    /**
     * 查询医生邀请的患者名单
     *
     * @param req
     * @return
     */
    @Override
    public IPage<DoctorInvitePatientPageRes> queryDoctorInvitePatientPageRes(PageReq req) {
        IPage<DoctorInvitePatientPageRes> iPage = req.pagePojo();
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        Integer doctorId = loginInfo.getId();
        iPage = getBaseMapper().queryDoctorInvitePatientPageRes(iPage, doctorId);
        return iPage;
    }

    @Autowired
    private IPresPrescriptionService presPrescriptionService;


    /**
     * 查询患者列表 运营后台 分页
     *
     * @param req
     * @return
     */
    @Override
    public IPage<PatientMedCardPageAdminRes> queryPatientMedCardPageAdmin(PatientMedCardPageAdminReq req) {
        IPage<PatientMedCardPageAdminRes> iPage = req.pagePojo();
        iPage = getBaseMapper().queryPatientMedCardPageAdmin(iPage, req);
        //获取就诊次数
        if (CollectionUtils.isNotEmpty(iPage.getRecords())) {
            for (PatientMedCardPageAdminRes res : iPage.getRecords()) {
                res.setNum(getNum(res.getMedId()));
            }
        }
        return iPage;
    }

    /**
     * 查询患者列表 运营后台 导出excel
     *
     * @param req
     */
    @Override
    public void exportPatientMedCardPageAdmin(PatientMedCardPageAdminReq req, HttpServletResponse response) {
        req.setPage(1);
        req.setPageSize(100);
        List<PatientMedCardAdminExcelRes> listRes = new ArrayList<>(100);
        IPage<PatientMedCardPageAdminRes> iPage;
        do {
            iPage = queryPatientMedCardPageAdmin(req);
            for (PatientMedCardPageAdminRes item : iPage.getRecords()) {
                PatientMedCardAdminExcelRes res = new PatientMedCardAdminExcelRes();
                BeanUtils.copyProperties(item, res);
                res.setAge(CalendarUtil.getAge(item.getBirthDate()).toString());
                item.setType(item.getType() == null ? 1 : item.getType());
                res.setType(item.getType() == 1 ? "线下诊疗" : "互联网问诊");
                listRes.add(res);
            }
            req.setPage(req.getPage() + 1);
        } while (iPage.getCurrent() < iPage.getPages());
        String title = "患者列表数据导出";
        try {
            ExtUtils.exportExcel(listRes, title, title, PatientMedCardAdminExcelRes.class, title, true, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private Integer getNum(String medId) {
        LambdaQueryWrapper<PresPrescription> preWrapper = new LambdaQueryWrapper<>();
        preWrapper.eq(PresPrescription::getMedId, medId).ne(PresPrescription::getStatus, -1).in(PresPrescription::getSourceType, ConsultConstants.Type.TYPES);
        Integer preCount = presPrescriptionService.count(preWrapper);
        LambdaQueryWrapper<ConsultSubscribe> csWrapper = new LambdaQueryWrapper<>();
        csWrapper.eq(ConsultSubscribe::getMedId, medId).in(ConsultSubscribe::getStatus, ConsultConstants.Status.ACCOUNT);
        Integer csCount = consultSubscribeService.count(csWrapper);
        return preCount + csCount;
    }

    /**
     * 智能开方添加或修改就诊卡信息
     *
     * @param req
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void aicmsSaveOrUpdateMedCard(AskDoctorParamsReq req) {
        LoginInfo loginInfo = UserInterceptor.getLoginUserInfo(LoginInfo.UserType.DOCTOR).get();
        //修改就诊卡
        PatientMedCard patientMedCard = null;
        if (StringUtils.isNotBlank(req.getMedId())) {
            QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
            qw.lambda().and(t -> t.eq(PatientMedCard::getMedId, req.getMedId())).ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
            patientMedCard = getOne(qw);
        }
        if (StringUtils.isNotBlank(req.getLXDH())) {
            QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
            qw.lambda().and(t -> t.eq(PatientMedCard::getMobileNumber, req.getLXDH())).ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
            patientMedCard = getOne(qw);
        }
        if (patientMedCard == null) {
            patientMedCard = new PatientMedCard();
            String medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            while (true) {
                QueryWrapper<PatientMedCard> qws = new QueryWrapper<>();
                qws.lambda().eq(PatientMedCard::getMedId, medNo);
                int count = count(qws);
                if (count == 0) {
                    break;
                }
                medNo = SerialNumberUtils.getInstance().medSerialNumber(redisTemplate);
            }
            patientMedCard.setMedId(medNo);
            patientMedCard.setDoctorId(loginInfo.getId());
            patientMedCard.setName(req.getXM());
            patientMedCard.setNamePinyin(PinYinUtils.chineseToPinyinSell(req.getXM()));
            patientMedCard.setContactAddress(req.getTXDZ());
            patientMedCard.setContagionHistory(req.getContagionHistory());
            patientMedCard.setDrugAllergyHistory(req.getDrugAllergyHistory());
            patientMedCard.setFamilyMedicalHistory(req.getFamilyMedicalHistory());
            patientMedCard.setMobileNumber(req.getLXDH());
            patientMedCard.setPregnant(req.getPregnant());
            patientMedCard.setNationality(req.getZB());
            patientMedCard.setMaritalStatus(req.getHYZK());
            patientMedCard.setIdCard(req.getIdCard());
            patientMedCard.setBirthDate(req.getBirthDate());
            patientMedCard.setSex(req.getXB());
            patientMedCard.setStatus(UserConstants.MedCardStatus.NORMAL);
            patientMedCard.setCreateDate(LocalDateTime.now());
            String img = getPhotoImg(req.getXB());
            patientMedCard.setAvatar(img);
            save(patientMedCard);
        } else {
            doctorPatientBindService.doctorPatientBind(loginInfo.getId(), patientMedCard.getMedId(), 1);
        }
        req.setMedId(patientMedCard.getMedId());
    }

    /**
     * 开处方生成患者信息
     *
     * @param patientReq
     * @param addrReq
     * @param loginInfo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public PatientMedCard addPresGeneratePatientInfo(PresPatientReq patientReq, PresPatientAddrReq addrReq, LoginInfo loginInfo) {
        PatientMedCard medCard = null;
        if (StringUtils.isNotBlank(patientReq.getMobileNumber())) {
            QueryWrapper<PatientMedCard> qw = new QueryWrapper<>();
            qw.lambda().eq(PatientMedCard::getMobileNumber, patientReq.getMobileNumber()).ne(PatientMedCard::getStatus, UserConstants.MedCardStatus.DEL);
            medCard = getOne(qw);
        }
        if (medCard == null) {
            medCard = new PatientMedCard();
            BeanUtils.copyProperties(patientReq, medCard);
            PatientMedCardCreateReq cardCreateReq = new PatientMedCardCreateReq();
            BeanUtils.copyProperties(patientReq, cardCreateReq);
            addPatientMedCard(cardCreateReq);
            medCard.setMedId(cardCreateReq.getMedId());
        } else {
            doctorPatientBindService.doctorPatientBind(loginInfo.getId(), medCard.getMedId(), 1);
        }
        if (addrReq != null) {
            PatientDeliveryAddrCreateReq addrCreateReq = new PatientDeliveryAddrCreateReq();
            BeanUtils.copyProperties(addrReq, addrCreateReq);
            addrCreateReq.setMedId(medCard.getMedId());
            patientDeliveryAddrService.addPatientDeliveryAddr(addrCreateReq);
        }
        return medCard;
    }

}
